package com.xs.tool;

import com.alibaba.fastjson.serializer.PropertyPreFilter;

import java.util.*;

public class JsonUtil {

    /**
     * 剔除 null、空字符串、空对象、空数组、空 Map 等空值字段
     */
    public static PropertyPreFilter getEmptyValueFilter() {
        return (serializer, value,property) -> {
            if (Objects.isNull(value)) return false;

            // 排除 Boolean 类型
            if (value instanceof Boolean) {
                return true;
            }

            // 空字符串
            if (value instanceof String str && str.isEmpty()) {
                return false;
            }

            // 空 Map（包括 JSONObject）
            if (value instanceof Map<?, ?> map && map.isEmpty())
            {
                return false;
            }

            // 数组
            if (value.getClass().isArray()) {
                int length = java.lang.reflect.Array.getLength(value);
                if (length == 0) return false;

                // 判断是否所有元素都为空
                boolean allEmpty = true;
                for (int i = 0; i < length; i++) {
                    if (!isEmptyValue(java.lang.reflect.Array.get(value, i))) {
                        allEmpty = false;
                        break;
                    }
                }
                if (allEmpty) return false;
            }

            // 集合类（List/Set/Iterable）
            if (value instanceof Iterable<?> iterable) {
                if (!iterable.iterator().hasNext()) {
                    return false; // 空集合
                }

                // 如果集合内全是空对象，则也剔除
                boolean allEmpty = true;
                for (Object item : iterable) {
                    if (!isEmptyValue(item)) {
                        allEmpty = false;
                        break;
                    }
                }
                return !allEmpty;
            }

            return true;
        };
    }


    private static boolean isEmptyValue(Object obj) {
        if (obj == null) return true;
        if (obj instanceof String s && s.isEmpty()) return true;
        if (obj instanceof Map<?, ?> m && m.isEmpty()) return true;
        if (obj instanceof Iterable<?> iter && !iter.iterator().hasNext()) return true;
        return obj.getClass().isArray() && java.lang.reflect.Array.getLength(obj) == 0;
    }
}